package com.erp.dao;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.transform.Transformers;

@SuppressWarnings("unchecked")
public class BaseDAO<T> {

	private SessionFactory sessionFactory;
	protected Class<T> classType;

	@SuppressWarnings("rawtypes")
	public BaseDAO() {
		// 通过反射得到T的真实类型
		ParameterizedType pt = (ParameterizedType) this.getClass()
				.getGenericSuperclass();
		this.classType = (Class) pt.getActualTypeArguments()[0];
	}

	public SessionFactory getSessionFactory() {
		return sessionFactory;
	}

	@Resource(name = "sessionFactory")
	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

	public Serializable save(T entity) {
		Session session = this.sessionFactory.getCurrentSession();
		return session.save(entity);
	}

	public void saveOrUpdate(T entity) {
		this.sessionFactory.getCurrentSession().saveOrUpdate(entity);
	}

	public void deleteById(Integer id) {
		T entity = this.getById(id);
		this.delete(entity);
	}

	public void delete(T entity) {
		Session session = this.sessionFactory.getCurrentSession();
		session.delete(entity);
	}

	public void update(T entity) {
		Session session = this.sessionFactory.getCurrentSession();
		session.update(entity);
	}

	/**
	 * 根据ID获取对象实例
	 * 
	 * @param id
	 * @return
	 */
	public T getById(Serializable id) {
		Session session = this.sessionFactory.getCurrentSession();
		Object o = session.get(classType, id);
		return (T) o;

	}

	/**
	 * 获取查询结果的第一个结果并返回对象实例
	 * 
	 * @param hql
	 * @return
	 */
	public T getFirst(String hql) {
		Query query = this.sessionFactory.getCurrentSession().createQuery(hql);
		T t = (T) query.setFirstResult(0).setMaxResults(1).uniqueResult();
		return t;
	}

	/**
	 * 执行hql获取0个或1个结果，返回对象实例
	 * 
	 * @param hql
	 * @return
	 */
	public T get(String hql) {
		Query query = this.sessionFactory.getCurrentSession().createQuery(hql);
		T t = (T) query.uniqueResult();
		return t;
	}

	/**
	 * 执行带占位符的hqi并返回对象实例
	 * 
	 * @param hql
	 * @return
	 */
	public T get(String hql, Map<String, Object> args) {
		Session session = this.sessionFactory.getCurrentSession();
		Query query = session.createQuery(hql);
		if (args != null && !args.isEmpty()) {
			for (String key : args.keySet()) {
				query.setParameter(key, args.get(key));
			}
		}
		T t = (T) query.uniqueResult();
		return t;
	}

	/**
	 * 查询实现该泛型的类所有集和
	 * 
	 * @return
	 */
	public List<T> listAll() {
		Session session = this.sessionFactory.getCurrentSession();
		Query query = session.createQuery("from " + classType.getSimpleName());
		List<T> temp = query.list();
		return temp;
	}

	/**
	 * 对实现该泛型的类所有集和进行分页
	 * 
	 * @return
	 */
	public List<T> paging(int firstResult, int maxResults) {
		Session session = this.sessionFactory.getCurrentSession();
		Query query = session.createQuery("from " + classType.getSimpleName());
		query.setFirstResult(firstResult);
		query.setMaxResults(maxResults);
		List<T> temp = query.list();
		return temp;
	}

	/**
	 * 对查询结果分页
	 * 
	 * @param string
	 * @return
	 */
	public List<T> paging(String hql, int firstResult, int maxResults) {
		Session session = this.sessionFactory.getCurrentSession();
		Query query = session.createQuery(hql);
		query.setFirstResult(firstResult);
		query.setMaxResults(maxResults);
		List<T> temp = query.list();
		return temp;
	}

	/**
	 * 对有占位符的HQL的查询结果分页
	 * 
	 * @param hql
	 * @param args
	 * @param firstResult
	 * @param maxResults
	 * @return
	 */
	public List<T> paging(String hql, Map<String, Object> args,
			int firstResult, int maxResults) {
		Session session = this.sessionFactory.getCurrentSession();
		Query query = session.createQuery(hql);
		if (args != null && !args.isEmpty()) {
			for (String key : args.keySet()) {
				query.setParameter(key, args.get(key));
			}
		}
		query.setFirstResult(firstResult);
		query.setMaxResults(maxResults);
		List<T> temp = query.list();
		return temp;
	}

	/**
	 * 执行数据查询语言（DQL），返回结果列表
	 * 
	 * @param hql
	 * @return
	 */
	public List<T> list(String hql) {
		Session session = this.sessionFactory.getCurrentSession();
		Query query = session.createQuery(hql);
		List<T> temp = query.list();
		return temp;
	}

	/**
	 * 根据ID集合查询出对应列
	 * 
	 * @param idList
	 *            ID集合
	 * @return
	 */
	public List<T> list(List<Integer> idList) {
		Session session = this.sessionFactory.getCurrentSession();
		if (idList == null) {
			return null;
		}
		StringBuffer hqlBuffer = new StringBuffer("from "
				+ classType.getSimpleName() + " where id in (");
		Iterator<Integer> it = idList.iterator();
		if (it.hasNext()) {
			hqlBuffer.append(it.next());
			while (it.hasNext()) {
				hqlBuffer.append("," + it.next());
			}
		}
		hqlBuffer.append(")");
		Query query = session.createQuery(hqlBuffer.toString());
		List<T> temp = query.list();
		return temp;
	}

	/**
	 * 执行有占位符的DQL语句
	 * 
	 * @param hql
	 * @param args
	 * @return
	 */
	public List<T> list(String hql, Map<String, Object> args) {
		Query query = this.sessionFactory.getCurrentSession().createQuery(hql);
		if (args != null && !args.isEmpty()) {
			for (String key : args.keySet()) {
				query.setParameter(key, args.get(key));
			}
		}
		return query.list();
	}

	/**
	 * 对DQL语句的查询结果分页
	 * 
	 * @param hql
	 * @param page
	 * @param rows
	 * @return
	 */
	public List<T> list(String hql, int page, int rows) {
		Query query = this.sessionFactory.getCurrentSession().createQuery(hql);
		return query.setFirstResult((page - 1) * rows).setMaxResults(rows)
				.list();
	}

	/**
	 * 对有占位符的DQL语句的查询结果分页
	 * 
	 * @param hql
	 * @param args
	 * @param page
	 * @param rows
	 * @return
	 */
	public List<T> list(String hql, Map<String, Object> args, int page, int rows) {
		Query query = this.sessionFactory.getCurrentSession().createQuery(hql);
		if (args != null && !args.isEmpty()) {
			for (String key : args.keySet()) {
				query.setParameter(key, args.get(key));
			}
		}
		return query.setFirstResult((page - 1) * rows).setMaxResults(rows)
				.list();
	}

	/**
	 * 统计实现泛型的类所有的集和size
	 * 
	 * @return
	 */
	public Long countAll() {
		Session session = this.sessionFactory.getCurrentSession();
		Query query = session.createQuery("select count(*) from "
				+ classType.getSimpleName());
		Long total = (Long) query.uniqueResult();
		return total;
	}

	/**
	 * 通常用于统计结果数
	 * 
	 * @param hql
	 * @return
	 */
	public Long count(String hql) {
		Session session = this.sessionFactory.getCurrentSession();
		Query query = session.createQuery(hql);
		Long total = (Long) query.uniqueResult();
		return total;
	}

	public Long count(String hql, Map<String, Object> args) {
		Session session = this.sessionFactory.getCurrentSession();
		Query query = session.createQuery(hql);
		if (args != null && !args.isEmpty()) {
			for (String key : args.keySet()) {
				query.setParameter(key, args.get(key));
			}
		}
		Long total = (Long) query.uniqueResult();
		return total;
	}

	/**
	 * 执行数据操纵语言（DML），返回影响的行数
	 * 
	 * @param hql
	 * @return
	 */
	public int executeHql(String hql) {
		Query query = this.sessionFactory.getCurrentSession().createQuery(hql);
		return query.executeUpdate();
	}
	
	/**
	 * 执行数据操纵语言（DML），返回影响的行数
	 * 
	 * @param sql
	 * @return
	 */
	public int executeSql(String sql) {
		Query query = this.sessionFactory.getCurrentSession().createSQLQuery(sql);
		return query.executeUpdate();
	}

	/**
	 * 执行数据操纵语言（DML），返回影响的行数
	 * 
	 * @param sql
	 * @return
	 */
	public List<Map<String,String>> getMapByQuery(String sql) {
		Query query = this.sessionFactory.getCurrentSession().createSQLQuery(sql)
				.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
		return query.list();
	}
	
	public List<String> getStringListByQuery(String sql) {
		Query query = this.sessionFactory.getCurrentSession().createSQLQuery(sql);
		return query.list();
	}

}
